﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////


#ifndef PARADEFINEDLG_H
#define PARADEFINEDLG_H

#pragma once
#include "ComponentEditorGnufUI.h"
#include "IFamilyParameterDefinition.h"
#include "FamilyParameterType.h"
#include <QtWidgets/QDialog>
#include <QLineEdit>
#include <QCompleter> 

class IExprEngine;
namespace Ui
{
    class ParaDefineDlg;
}

namespace gfam
{
    class IFamilyManager;
    class IFamilyDimensionConstraint;
    class ExprAssistantDlg;
    struct SharedParaDefineData;

    class COMPONENT_EDITOR_GNUF_UI_EXPORT DelimitedCompleter : public QCompleter
    {
        Q_OBJECT

    public:
        DelimitedCompleter(QLineEdit *parent, const QStringList &list);
        QString pathFromIndex(const QModelIndex &index) const;
        QStringList splitPath(const QString &path) const;

        int GetPosition();

    private:
        bool eventFilter(QObject *object, QEvent *event);

    private:
        mutable int m_position;          //光标位置，用于表达式联想完成后设置光标位置
        mutable bool m_isNeedEscape;
        mutable bool m_isNeedUpdate;
    };

    class COMPONENT_EDITOR_GNUF_UI_EXPORT ParaDefineDlg : public QDialog
    {
        Q_OBJECT

    public:
        ParaDefineDlg(gfam::FamilyParameterType familyParameterType, bool bTypeEditable = true, QWidget *parent = 0);
        ~ParaDefineDlg();

        void SetFamilyManager(IFamilyManager* pFamilyManager) { m_pFamilyManager = pFamilyManager; }
        QString GetParamStrName() { return m_strParaName; }
        std::wstring GetParamStrValue() { return m_strParaValue; }
    public:
        virtual void accept() override;

        bool CreateNewParameter(const std::wstring& strName, int nType, bool bInstance, bool bFomula, const std::wstring& strFomula, const std::wstring & strValue);

        bool ModifyParameter(const std::wstring& strName, int nType, bool bInstance, bool bFomula, const std::wstring& strFomula, const std::wstring & strValue);

        void InitToModify(const QString& qstrName);

        void SetFormulaLineEditText(const QString& qStrValue);

        std::wstring ConvertParameterType(FamilyParameterType type);

        void UpdateComboBoxIndex(const IFamilyParameterDefinition* pParam, const QString& qStrValue);

    public Q_SLOTS:
        void OnSelectParameterFile();
        void OnChangeButtonState(int id, bool checked);

        void OnTypeComboBoxTextChanged();
        void OnMaterialComboBoxTextChanged();
        void OnTextStyleComboBoxTextChanged();
        void OnHelpButtonClicked();

        void OnCursorPositionChanged();

        // 日志系统暂未支持QCompleter控件，在回放时QLineEdit::SetText未触发QListView,导致脚本不过，需要手动弹出联想下拉列表
        void OnFormulaTextChangedInReplay();

    private:

        void onMoveRequested(const QPoint& cursorPos, const QPoint& offset);

        void UpdateDimConstraintBoundToOldParam(std::vector<IFamilyDimensionConstraint *> vecDimConstraintsBoundToCurParam, IFamilyParameterDefinition* pParam);

        IFamilyParameterDefinition* AddNewFamilyParameterWithSameName(const std::wstring& strName, int nType, bool bInstance, bool bFomula, const std::wstring& strFomula);

        void GetDimConstraintBoundToCurrentParam(std::vector<IFamilyDimensionConstraint *> &vecDimConstraintsLinkedToCurParam);

        void UpdateParameterBindingInfo(int oldParamDefId, int newParamDefId);

        void SwapParameterDefinitionDisplayOrder(int modifyParamIndex) const;

        bool CheckParameterValue(int nType, const std::wstring &strValue);

        bool ModifyParameterValue(const IFamilyParameterDefinition* pParam, const std::wstring& familyTypeName, const std::wstring& strValue);

        QString ParamValueToString(const IFamilyParameterDefinition* pParam);

        bool IsParamValueChanged(const IFamilyParameterDefinition* pParam, const std::wstring& strValue);

        // 更新表达式的值
        bool UpdateParamExprValues();

        // 可能新增了一个材质，下拉列表需更新。materialName是材质实例的名称
        void UpdateMaterialComboBox(const std::wstring& materialName);

        // 计算出材质下拉列表中可见的内容
        std::vector<std::wstring> CalcItemNamesInMaterialComboBox();
        std::vector<std::wstring> CalcItemNamesOfRichTextComboBox();

        void InitCompleter();

    private:
        gcmp::OwnerPtr<Ui::ParaDefineDlg> ui;
        bool m_bModify;
        QString m_strParaName;
        std::wstring m_strParaValue;

        const IFamilyParameterDefinition* m_pModifedParaDefinition;
        IFamilyManager* m_pFamilyManager;
        gcmp::OwnerPtr<SharedParaDefineData> m_sharedParaData;//保存选择的共享参数数据用于创建参数
        gcmp::ElementId m_materialId;
        gcmp::OwnerPtr<ExprAssistantDlg> m_exprAssistantDlg;

    public:
        int m_iType;
    };
}

#endif // PARADEFINEDLG_H
